package com.ocp.macro.aspect;

import com.ocp.macro.annotation.AutowireUserToken;
import com.ocp.macro.entity.UserInfoToken;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class UserTokenInfoPointCut {
    @Pointcut("@annotation(com.ocp.macro.annotation.AutowireUserToken)")
    public void UserTokenInfoPoint(){}

    /*
        使用了此切面的方法，会对方法的UserInfoToken类的字段赋值，用户获取当前登录账号的信息
     */
    @Around(value="UserTokenInfoPoint()")
    public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs(); // 获取代理方法的参数列表
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        AutowireUserToken annotation = signature.getMethod().getAnnotation(AutowireUserToken.class);
        String[] parameterNames = signature.getParameterNames(); // 获取代理方法的参数名列表
        Class<?>[] parameterTypes = signature.getParameterTypes(); // 获取代理方法的参数类型列表
        for (int i = 0; i < args.length; i++){
            if (parameterNames[i].equals(annotation.name())
                    && parameterTypes[i].equals(UserInfoToken.class)){
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                UserInfoToken userToken = (UserInfoToken) authentication.getPrincipal();
                args[i] = userToken; // 对对应的字段赋值
                log.debug("环绕加强：{}",args[i]);
            }
        }

        return joinPoint.proceed(args);
    }
}
